package com.newegg.hardware.benchmark.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.newegg.hardware.benchmark.dao.HardmarkMapper;
import com.newegg.hardware.benchmark.dao.HistoryMapper;
import com.newegg.hardware.benchmark.model.ExpiredObject;
import com.newegg.hardware.benchmark.model.Hardmark;
import com.newegg.hardware.benchmark.model.History;
import com.newegg.hardware.benchmark.model.MarkCount;
import com.newegg.hardware.benchmark.model.Score;
import com.newegg.hardware.benchmark.service.MarkMean.Range;

@Service
public class DiskScoreService implements HardwareServiceHander{
	static String TYPE = "DISK";
	@Autowired
	HardmarkMapper hardmarkMapper;
	@Autowired
	HistoryMapper historyMapper;
	
	ExpiredObject<Range> range;
	
	static String getName(JSONObject data) {
		String name = data.getString("Model");
		if(name == null) { return null; }
		if(name.lastIndexOf("-") != -1) {
			name = name.substring(0, name.lastIndexOf("-"));
		}
		if(name.indexOf("_") != -1) {
			name = name.substring(name.indexOf("_") + 1);
		}
		return name.toLowerCase().trim();
	}
	
	public Hardmark getScoreByName(String name) {
		if(name == null) { return null; }
		Hardmark mark = hardmarkMapper.find(name, TYPE);
		if(mark == null && name.indexOf("-") != -1) {
			name = name.substring(0, name.lastIndexOf("-"));
			mark = hardmarkMapper.find(name, TYPE);
		}
		if(mark == null&& name.indexOf("_") != -1) {
			name = name.substring(name.indexOf("_") + 1);
			mark = hardmarkMapper.find(name, TYPE);
		}
		if(mark == null) {
			name = "%" + name.replace(" ", "%") + "%";
			mark = getByHistory(name);
		}
		return mark;
	}
	
	@Override
	public Score getExistScore(JSONArray datas) {
		JSONObject data = getMainDisk(datas);
		String name = getName(data);
		Hardmark mark = getScoreByName(name);
		if(mark == null || mark.getMark() == null) { return null; }
		Score result = new Score();
		result.setScore(mark.getMark());
		result.setMean(getMeanScore());
		result.setStar(getStar(result.getScore()));
		result.setSimulate(mark.getSimulate());
		return result;
	}

	@Override
	public int getMeanScore() {
		if(range == null || range.isExpired()) {
			initRange();
		}
		return range.get().mean;
	}
	
	@Override
	public int getStar(int score) {
		if(range == null || range.isExpired()) {
			initRange();
		}
		Range r = range.get();
		int start = r.start;
		int end = r.end;
		if(score < start) { return 1; }
		if(score > end) { return 5; }
		return (int) Math.ceil((score - start) / Math.ceil((end - start) / 5));
	}
	
	private void initRange() {
		List<MarkCount> markcounts = hardmarkMapper.marks(TYPE);
		Range result = MarkMean.getMarkRange(markcounts);
		if(result == null) {
			Integer mean = hardmarkMapper.mean(TYPE);
			mean = mean == null ? 800 : mean;
			result = new Range(mean - 500, mean + 500, mean);
		}
		range = new ExpiredObject<Range>(result, 24 * 60 * 60 * 1000);
	}

	@Override
	public int getVirtulScore(JSONArray datas, Integer defaultScore) {
		if(defaultScore != null && defaultScore > 0) { return defaultScore; }
		JSONObject disk = getMainDisk(datas);
		if(disk.containsKey("DiviceType") && "SSD".equals(disk.getString("DiviceType".toUpperCase()))) {
			return getMeanScore() + 500;
		}
		return getMeanScore();
	}
	
	static JSONObject getMainDisk(JSONArray datas) {
		for (int i = 0; i < datas.size(); i++) {
			JSONObject data = datas.getJSONObject(i);
			if(data.containsKey("BootPartition") && data.getBooleanValue("BootPartition")) {
				return data;
			}
		}
		return datas.getJSONObject(0);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public void insertHistory(JSONArray datas, Score score) {
		if(score == null || score.getScore() <= 0) { return; }
		JSONObject data = getMainDisk(datas);
		String name = getName(data);
		//将当前跑分的硬件信息入库
		History history = new History();
		history.setName(name);
		history.setType(TYPE);
		history.setManufacture(data.getString("Manufacturer"));
		history.setFamily(data.getString("FirmwareRevision"));
		history.setModel(data.getString("Name"));
		history.setFullname(data.getString("Model"));
		history.setDriver(data.getString("Caption"));
		history.setSerial(data.getString("SerialNumber"));
		history.setMark(score.getScore());
		historyMapper.insert(history);
	}
	
	@Override
	public Hardmark getByHistory(String name) {
		History score = historyMapper.seachByName(name, TYPE);
		if(score == null) { return null; }
		Hardmark mark = new Hardmark();
		mark.setName(score.getName());
		mark.setMark(score.getMark());
		mark.setSimulate(false);
		mark.setType(TYPE);
		return mark;
	}
}
